package RateService

import (
	RateDto "blog/app/dto/rate_dto"
	RateModel "blog/app/models/rate_model"
	"blog/config"
	"blog/service"
	"blog/utils"
	"blog/utils/tools"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/spf13/viper"
	"io"
	"log"
	"net/http"
	"strconv"
	"time"
)

// GetRateLatest 使用API获取最新汇率列表
func GetRateLatest(c *gin.Context) {
	url := "https://api.apilayer.com/exchangerates_data/latest?symbols=symbols&base=base"

	url = "http://127.0.0.1:7890" + "/exchangerates_data/latest?symbols=symbols&base=base"

	client := &http.Client{}
	req, err := http.NewRequest("GET", url, nil)
	req.Header.Set("apikey", "awBXKhev6DcBV0qTxstrflp1zzAAcfox")

	if err != nil {
		fmt.Println(err)
	}
	res, err := client.Do(req)
	if res.Body != nil {
		defer func(Body io.ReadCloser) {
			err := Body.Close()
			if err != nil {
				fmt.Println(err)
			}
		}(res.Body)
	}
	body, err := io.ReadAll(res.Body)
	if err != nil {
		fmt.Println(err)
		return
	}
	var rateDtoData RateDto.ExchangeRates

	err = json.Unmarshal(body, &rateDtoData)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("查看解析结果", rateDtoData.Base)

	nowTime := time.Now()
	for index, item := range rateDtoData.Rates {
		rateTime, _ := tools.TryParseTime(rateDtoData.Date)
		saveItem := RateModel.RateRecord{
			FromCode:    rateDtoData.Base,
			ToCode:      index,
			Rate:        strconv.FormatFloat(item, 'f', 4, 64),
			RateTime:    strconv.FormatInt(rateDtoData.Timestamp, 10),
			RateDate:    rateTime,
			CreatedTime: nowTime,
			UpdatedTime: nowTime,
			CreatedBy:   "system",
			UpdatedBy:   "system",
		}
		fmt.Println(index, item)

		err := utils.MySqlDB.Model(&RateModel.RateRecord{}).Create(&saveItem)
		if err.Error != nil {
			fmt.Printf("Error creating item: %v\n", err)
		}
	}
	service.CommonCJsonReply(c, config.SUCCESS, rateDtoData)
}

// GetRateByDate 按日期段请求数据
func GetRateByDate(c *gin.Context) {
	// 自动生成2020年全年每个月的开始日期和结束日期
	yearReq := c.Query("year")
	// year 转为 int 类型
	year, _ := strconv.Atoi(yearReq)
	GetDataByYear(year)
	service.CommonCJsonReply(c, config.SUCCESS, "ok")
}

// GetDataByYear 根据年份按月请求数据
func GetDataByYear(year int) {
	// 设置为该年的第一天
	startOfYear := time.Date(year, time.January, 1, 0, 0, 0, 0, time.UTC)

	// 循环遍历每个月
	for month := startOfYear.Month(); month <= time.December; month++ {
		// 获取当前月的第一天
		firstDayOfMonth := time.Date(year, month, 1, 0, 0, 0, 0, time.UTC)

		// 获取下个月的第一天，然后减去一天得到当前月的最后一天
		lastDayOfMonth := firstDayOfMonth.AddDate(0, 1, -1)

		startDate := firstDayOfMonth.Format("2006-01-02")
		endDate := lastDayOfMonth.Format("2006-01-02")
		log.Println("开始获取数据写入mysql,开始日期" + startDate + "结束日期:" + endDate)
		// 并发请求数据
		go ReqDataByDate(startDate, endDate)
	}
}

// AutoDeal 自动处理
func AutoDeal(c *gin.Context) {
	// 自动处理数据 2016-2021年的按月获取
	for year := 2016; year <= 2021; year++ {
		fmt.Println("开始获取数据写入mysql,开始日期", year)
		go GetDataByYear(year)
	}
	// 获取2022和2023年只需要上半年和下半年参数
	for year := 2022; year <= 2023; year++ {
		startDate := strconv.Itoa(year) + "-01-01"
		start2Date := strconv.Itoa(year) + "-07-01"
		fmt.Println("开始获取数据写入mysql,开始日期", year, startDate, start2Date)
		go ReqDataByDate(startDate, "2022-06-30")
		go ReqDataByDate(start2Date, "2022-12-31")
	}

	// 处理 2024年
	startDate := "2024-01-01"
	fmt.Println("2024年开始获取数据写入mysql,开始日期", startDate)
	go ReqDataByDate(startDate, "2024-06-30")
	// 5-11月

	year := 2024
	startOfYear := time.Date(year, time.January, 1, 0, 0, 0, 0, time.UTC)

	// 循环遍历每个月
	for month := startOfYear.Month(); month < time.December; month++ {
		// 跳过 1-4月的数据
		fmt.Println("跳过 1-4月的数据", month)
		if month < time.May {
			continue
		}
		// 获取当前月的第一天
		firstDayOfMonth := time.Date(year, month, 1, 0, 0, 0, 0, time.UTC)

		// 获取下个月的第一天，然后减去一天得到当前月的最后一天
		lastDayOfMonth := firstDayOfMonth.AddDate(0, 1, -1)

		startDate := firstDayOfMonth.Format("2006-01-02")
		endDate := lastDayOfMonth.Format("2006-01-02")
		log.Println("开始获取数据写入mysql,开始日期" + startDate + "结束日期:" + endDate)
		// 并发请求数据
		go ReqDataByDate(startDate, endDate)
	}
}

func ReqDataByDate(startDate, endDate string) {
	log.Println("开始获取数据写入mysql,开始日期" + startDate + "结束日期:" + endDate)
	hostUrl := viper.GetString("apilayer.host")

	//url := "https://api.apilayer.com/exchangerates_data/timeseries?start_date=2024-09-01&end_date=2024-09-30"
	url := hostUrl + "/exchangerates_data/timeseries?start_date=" + startDate + "&end_date=" + endDate

	log.Println("查看url" + url)

	client := &http.Client{}
	req, err := http.NewRequest("GET", url, nil)
	req.Header.Set("apikey", "awBXKhev6DcBV0qTxstrflp1zzAAcfox")

	if err != nil {
		fmt.Println(err)
		log.Println(err)
	}
	res, err := client.Do(req)
	if res.Body != nil {
		defer func(Body io.ReadCloser) {
			err := Body.Close()
			if err != nil {
				fmt.Println(err)
			}
		}(res.Body)
	}
	body, err := io.ReadAll(res.Body)
	if err != nil {
		fmt.Println(err)
		log.Println(err)
		return
	}
	var ratePeriod RateDto.ExchangeRatesPeriod
	err = json.Unmarshal(body, &ratePeriod)
	if err != nil {
		fmt.Println(err)
		log.Println(err)
		return
	}
	for indexDate, item := range ratePeriod.Rates {
		for indexCode, item2 := range item {
			rateTime, _ := tools.TryParseTime(indexDate)
			saveItem := RateModel.RateRecord{
				FromCode:    ratePeriod.Base,
				ToCode:      indexCode,
				Rate:        strconv.FormatFloat(item2, 'f', 4, 64),
				RateTime:    indexDate, // 这个就没有时间戳,只有日期
				RateDate:    rateTime,
				CreatedTime: time.Now(),
				UpdatedTime: time.Now(),
				CreatedBy:   "system",
				UpdatedBy:   "system",
			}
			err := utils.MySqlDB.Model(&RateModel.RateRecord{}).Create(&saveItem)
			if err.Error != nil {
				fmt.Printf("Error creating item: %v\n", err)
				log.Printf("Error creating item: %v\n\n", err)
			}
		}
	}
	log.Println("获取数据写入mysql完成")
}
